<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

</body>

<!--例子--------------------------------------------------------------------------------------------------------------->
<script type="text/html">
    //
    // 创建父构造函数
    function Person(name, age) {
    this.name = name;
    this.age = age;
    this.showName = function () {
    console.log(this.name);
    }
    }

    // 设置父构造函数的原型对象
    Person.prototype.showAge = function () {
    console.log(this.age);
    };

    // 创建子构造函数
    function Student(name) {
    Person.call(this, name);
    }

    // 设置继承
    // Student.prototype = Person.prototype;
    // Student.prototype.constructor = Student;
    // 上面代码解决了 父构造函数的属性继承到了子构造函数的实例对象上了,
    // 并且继承了父构造函数原型对象上的成员,
    // 解决了给父构造函数传递参数问题
    // 但是还有共享的问题
    var p1 = new Person("小强", 30);
    var s1 = new Student("小明");
    console.log(p1);
    console.log(s1);
    console.log(s1 instanceof Person);
    console.log(s1 instanceof Student);
</script>

<!--组合式继承---------------------------------------------------------------------------------------------------------->
<script type="text/html">
    //
    function Parent() {
    this.name = "parent";
    this.colors = ["red", "blue", "yellow"];
    }

    Parent.prototype.sex = "男";
    Parent.prototype.say = function () {
    console.log("Oh, My God！")
    };

    function Child() {
    Parent.call(this);
    this.type = "child";
    }

    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child;
    let c = new Child();
    console.log(c.sex);
    c.say();
</script>

<!--深拷贝----------------------------------------------------------------------------------------------------->
<script type="text/html">
    //
    function deepCopy(origin, target) {
    let toStr = Object.prototype.toString();
    let arrStr = '[object Array]';
    let ret = target || {};
    for (let prop in origin) {
    if (origin.hasOwnProperty(prop)) {
    if (origin[prop] !== null && typeof (origin[prop]) == 'object') {
    ret[prop] = toStr.call(origin[prop]) === arrStr ? [] : {};
    deepCopy(origin[prop], ret[prop]);
    } else
    ret[prop] = origin[prop];
    }
    }
    return ret;
    }

    function A(name) {
    this.name = name;
    }

    function B(name, age) {
    A.call(this, name);
    this.age = age;
    }

    deepCopy(A.prototype, B.prototype);
    console.log(A.prototype.hasOwnProperty(A.prototype.constructor));
    console.log(B.prototype.constructor === {}.constructor);
    // B.prototype.constructor = B;
    A.prototype.name = 'A';
    console.log(A.prototype.constructor);
    console.log(B.prototype.constructor);
    let a = new A('a');
    let b = new B('b', 18);
    console.log(a);
    console.log(b);
    console.log("不拷贝，直接引用，后果是，父类和子类的原型共享");
</script>

<!--圣杯模式------------------------------------------------------------------------------------------------------------>
<script type="text/html">
    //
    function Father() {

    }

    function Son() {

    }

    function inherit(A, B) {
    function F() {

    }

    // A.prototype = new F();
    F.prototype = B.prototype;
    A.prototype = new F();
    A.prototype.constructor = A;
    A.prototype.uber = B.prototype;
    }

    inherit(Son, Father);
    console.log(new Son().__proto__.__proto__ === Father.prototype);
    console.log(new Son().uber === Father.prototype);
</script>

<!--圣杯模式(雅虎写法)-------------------------------------------------------------------------------------------------->
<script>
    // type="text/html"
    function Father() {

    }

    function Son() {

    }

    function Son2() {

    }

    var inherit = (function () {
        function F() {

        }

        return function (A, B) {
            F.prototype = B.prototype;
            A.prototype = new F();
            A.prototype.constructor = A;
            A.prototype.uber = B.prototype;
        }
    }());

    inherit(Son, Father);
    inherit(Son2, Son);
    console.log(new Son().__proto__.__proto__ === Father.prototype);
    console.log(new Son().uber === Father.prototype);
    console.log(new Son2().__proto__.__proto__ === Son.prototype);
    console.log(new Son2().uber === Son.prototype);
</script>

<!--一个奇怪的东西------------------------------------------------------------------------------------------------------>
<script type="text/html">
    //
    var fakeArrayProto = Object.create(null);
    fakeArrayProto.push = Array.prototype.push;
    fakeArrayProto.splice = Array.prototype.splice;

    function getFakeArray() {
    return Object.create(fakeArrayProto);
    }

    var x = getFakeArray();
    console.log(x);
    x.push(1);
    x.push(2);
    x.push(3);
    x.push(4);
    console.log(x);
    console.log('x instanceof Array? ' + (x instanceof Array));
    console.log('x instanceof Object? ' + (x instanceof Object));
    console.log('typeof x? ' + typeof x);
    console.log('-------------------------------');
    var arr = [];
    console.log(arr);
    arr.push(1);
    arr.push(2);
    arr.push(3);
    arr.push(4);
    console.log(arr);
</script>

</html>